/**
 * @version		$Id$	
 * @create 			2012-7-16下午08:39:14 By zengxinyuan
 * @package 		com.xyrj.core
 * @copyRight 		Copyright (c) 2011-2012 http://www.xjiujiu.com.All right reserved
 * XYRJ-Framework
 */
package com.limit.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

import com.limit.exception.HHFileSystemException;
import com.limit.exception.HHNotFoundException;

/**
 * 文件操作类
 *  
 *  打开，新建，复制，删除文件等
 * 
 * @author 			zengxinyuan <liscy5394323@foxmail.com>
 * @package 		com.xyrj.filesystem
 * @since 			1.0.0
 */
public class HHFile
{
	/**
	 * 功能描述：打开文件到输入流
	 * @param filePath 文件名（包括文件的目录）
	 * @return  FileInputStream 文件输入流
	 */
	public static FileInputStream openFile(String filePath)
		throws HHFileSystemException
	{
		try {
            return  new FileInputStream(filePath);
        } catch (FileNotFoundException e) {
        	throw new HHFileSystemException("文件打开失败！", "打开失败文件的路径为：" + filePath);
		}
	}
	
	 /**
     * 功能描述：新建文件
     * @param filePath 文件名包括目录
     * @param override 是否覆盖
     * @throws 
     */
	public static void createFile(String filePath, Boolean override)
		throws HHNotFoundException, HHFileSystemException
	{
       if(filePath.endsWith(File.separator)) {  
    	   filePath 	= filePath.substring(-1);
       }
       File file = HHFile.isExists(filePath);
       if(!file.getParentFile().exists()
		  && !file.getParentFile().mkdir()) {
    	   throw new HHFileSystemException("不能创建对应的文件或目录！", "创建的文件或目录为：" + filePath);
       }
       try {
	       if(!file.createNewFile()) {
	    	   throw new HHFileSystemException("创建新文件或目录失败！", "创建失败新文件或目录为：" + filePath);
	       }
       } catch(IOException ex) {
    	   throw new HHFileSystemException("创建新文件或目录失败！", "创建失败新文件或目录为：" + filePath);
       }
   }
   
   /**
    * 功能描述：删除文件
    * @param filePath 文件名（包括目录）
    * @throws HHFileSystemException
    */
	public static void deleteFile(String filePath) 
		throws HHFileSystemException
	{
		try {
	        File file = HHFile.isExists(filePath);
			if(!file.isFile() || !file.delete()){
				throw new HHFileSystemException("删除文件失败！", "删除文件为：" + filePath);
            }
		} catch(HHNotFoundException ex) {
			System.out.println(ex.getMessage());
		}
	}
   
    /**
     * 功能描述：复制文件  
     * @param src 源文件的目录
     * @param dest 目标文件的目录
     * @return boolean 
     */
	public static boolean copyFile(String src, String dest) 
	{
        BufferedInputStream bin = null;
        BufferedOutputStream bout = null;
        File srcFile = new File(src);
        if(!srcFile.exists()) {
            return false;
        }
        if(!srcFile.isFile()) {    
            return false;
        }
        File destFile = new File(dest);
        if(!destFile.exists()){
            if(!destFile.getParentFile().exists()) {
              if(!destFile.getParentFile().mkdir()) {   
                  return false;
              }
            }
        }else {
            return false;
        }
        try {
            bin = new BufferedInputStream(new FileInputStream(src));
            bout = new BufferedOutputStream(new FileOutputStream(dest));
            byte[] buf = new byte[bin.available()];
            int len = 0;
            while((len=(bin.read(buf)))!=-1){
                bout.write(buf,0,len);
                bout.flush();
            }
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(bout != null) {
                try {
                    bout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bin != null) {
                try {
                    bin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

	/**
	 * 移动指定的文件 
	 *  
	 * 把目标文件移动到指定的路径，并删除源文件.
	 * 如果目标文件存在，则覆盖旧的文件 
	 * 
	 * @title  moveFile
	 * @param  String fromPath 来源路径
	 * @param  String toPath 目标路径
	 * @return boolean 是否移动成功
	 */
	public static void moveFile(String fromPath, String toPath, boolean isCover)
		throws HHFileSystemException
	{
		try {
			File to 	= new File(toPath);
			File from 	= HHFile.isExists(fromPath);
			if(to.exists()) {
				if(!isCover) {
					throw new HHFileSystemException(
						"文件已经存在！",
						"已经存在的文件路径为：" + toPath
					);
				}
				HHFile.deleteFile(toPath);
			}
			from.renameTo(to);
		} catch(HHNotFoundException ex) {
			throw new HHFileSystemException(ex.getMessage());
		}
	}

	/**
	 * 追加文件内容到文件 
	 *  
	 * @description 对现有的文件添加新的内容
	 * 
	 * @title appendFile
	 * @author xjiujiu <xjiujiu@foxmail.com>
	 * @param  String filePath 文件路径
	 * @param  String content 文件内容
	 * @param  boolean isNew 是否新建
	 * @throws HHFileSystemException 
	 */
	public static void appendFile(String filePath, String content, boolean isNew)
		throws HHFileSystemException
	{
		try {
			File file 			= new File(filePath);
			if(!file.exists()) {
				if(false == isNew) {
					throw new HHFileSystemException("文件不存在！");
				}
				file.createNewFile();
			}
			FileWriter writer 	= new FileWriter(filePath, true);
			writer.write(content);
			writer.close();
		} catch(IOException ex) {
			throw new HHFileSystemException("文件读取错误！");
		}
	}

	/**
	 * 得到文件名
	 *  
	 * 除扩展名的部分, 用法：<br/>
	 * <code>
	 * HHFile.getBaseName("test/test/text.txt"); //text
	 * </code> 
	 * 
	 * @title  getBaseName
	 * @param  String filePath 文件路径
	 * @return String 不包括扩展名的文件名部分
	 */
	public static String getBaseName(String filePath)
	{
		int start 	= filePath.lastIndexOf('/');
		int end 	= filePath.lastIndexOf('.');
		if(start < 0) {
			start 	= -1;
		}
		if(end < 0) {
			end 	= filePath.length();
		}
		
		return filePath.substring(++start, end);
	}

	/**
	 * 得到文件名
	 *  
	 * 包括文件的扩展名，用法：
	 * <br/>
	 * <code>
	 * HHFile.getName("/test/test/test.txt"); // test.txt
	 * </code> 
	 * 
	 * @title  getName
	 * @param  String filePath 文件路径
	 * @return String 文件名
	 */
	public static String getName(String filePath)
	{
		int start 	= filePath.lastIndexOf('/');
		if(start < 0) {
			start 	= -1;
		}
		
		return filePath.substring(++start);
	}

	/**
	 * 得到文件所在的目录
	 *  
	 * @description
	 * 
	 * @title  getParentDir
	 * @param  String filePath 文件路径
	 * @return String 文件所有目录
	 */
	public static String getParentDir(String filePath)
	{
		int start 	= filePath.lastIndexOf('/');
		if(start < 0) {
			start 	= 1;
		}
		
		return filePath.substring(0, --start);
	}

	/**
	 * 得到文件扩展名
	 *  
	 * 只是文件的扩展名包括"."，如<br/>
	 * <code>
	 * HHFile.getExtension("/test/test.txt"); //.txt
	 * </code> 
	 * 
	 * @title  getExtension
	 * @param  String filePath 需要处理文件路径
	 * @return String
	 */
	public static String getExtension(String filePath)
	{
		try {
			return filePath.substring(filePath.lastIndexOf("."));
		} catch(IndexOutOfBoundsException ex) {
			return null;
		}
	}

	/**
	 * 把MB单位换算成Byte
	 *  
	 * @description
	 * 
	 * @title  mbToByte
	 * @param  int mbSize 当前的MB 大小  
	 * @return int 换算后的结果
	 */
	public static double mbToByte(double mbSize)
	{
		return mbSize * 1024 * 1024;
	}

	/**
	 * 字节到M的单位转换
	 *  
	 * @description
	 * 
	 * @title byteToMb
	 * @author xjiujiu <xjiujiu@foxmail.com>
	 * @param  double bytes 字节数
	 * @return double 当前M
	 */
	public static double byteToMb(double bytes)
	{
		return bytes / 1024 / 1024;
	}

	/**
	 * 检测当前的文件是否存在
	 * 
	 * @description 如果当前的文件不存在，则抛出HHNotFoundException异常
	 * 
	 * @title  isExists
	 * @param  String filePath 需要检测的文件路径
	 * @return HFile 当前打开的文件对象
	 * @throws HHNotFoundException 没有找到对应文件异常
	 */
	public static File  isExists(String filePath)
		throws HHNotFoundException
	{
		File file 	= new File(filePath);
		if(!file.exists()) {
			throw new HHNotFoundException();
		}
		
		return file;
	}

	/**
	 * 修正文件路径
	 * 
	 * @description
	 * 
	 * @title  fixFilePath
	 * @param  filePath 文件路径
	 * @return 正确的文件路径
	 */
	public static String fixFilePath(String filePath)
	{
		if(!filePath.endsWith(File.separator)) {
			return filePath;
		}
		
		return filePath.substring(0, -1);
	}

	/**
	 * 得到文件的大小
	 *  
	 * @description 用法：
	 * <code>
	 * 	HHFile.getFileSize("/home/root/test.txt");  //23243 Bytes
	 * </code>
	 * 
	 * @title size
	 * @author xjiujiu <xjiujiu@foxmail.com>
	 * @param  String filePath 需要查看大小的文件路径
	 * @return double 文件的大小，单位Bytes
	 * @throws IOException
	 */
	public static double size(String filePath) throws IOException
	{
		File file 	= new File(filePath);
		if(!file.exists()) {
			throw new IOException("没有找到对应的文件！");
		}
		
		return file.length();
	}
	
}
